package com.turnengine.client.local.unit.list;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import com.turnengine.client.local.unit.enums.UnitType;

public class UnitList implements IUnitList {

	private final UnitType type;
	private final List<IParentUnit> parentList = new ArrayList<IParentUnit>();

	public UnitList(UnitType type) {
		if (type == null) {
			throw new NullPointerException("type");
		}
		this.type = type;
	}

	@Override
	public UnitType getUnitType() {
		return type;
	}

	@Override
	public boolean isEmpty() {
		return parentList.isEmpty();
	}

	@Override
	public void clear() {
		parentList.clear();
	}

	@Override
	public int parents() {
		return parentList.size();
	}

	@Override
	public int parents(int unitId) {
		int count = 0;
		for (IParentUnit parent : parentList) {
			if (parent.getUnitId() == unitId) {
				count++;
			}
		}
		return count;
	}

	@Override
	public void addParent(IParentUnit parent) {
		if (parent == null) {
			throw new NullPointerException("parent");
		}
		parentList.add(parent);
	}

	@Override
	public IParentUnit getParent(int unitId, int offset) {
		int index = 0;
		for (IParentUnit parent : parentList) {
			if (parent.getUnitId() == unitId) {
				if (index == offset) {
					return parent;
				}
				index++;
			}
		}
		throw new IllegalArgumentException("unitId=" + unitId + ", offset=" + offset);
	}

	@Override
	public IParentUnit getParentAtIndex(int index) {
		return parentList.get(index);
	}

	@Override
	public boolean containsParent(int unitId) {
		for (IParentUnit parent : parentList) {
			if (parent.getUnitId() == unitId) {
				return true;
			}
		}
		return false;
	}

	@Override
	public boolean containsChild(int unitId) {
		for (IParentUnit parent : parentList) {
			if (parent.containsChild(unitId)) {
				return true;
			}
		}
		return false;
	}

	@Override
	public void addParentAmount(int unitId, int amount) {
		if (amount < 0) {
			throw new IllegalArgumentException("amount=" + amount);
		}
		for (int i = 0; i < amount; i++) {
			IParentUnit parent = new ParentUnit(unitId);
			parentList.add(parent);
		}
	}

	@Override
	public void removeParentAmount(int unitId, int amount) {
		throw new UnsupportedOperationException("Method Not Implemented");
	}

	@Override
	public int getParentAmount(int unitId) {
		int amount = 0;
		for (IParentUnit parent : parentList) {
			if (parent.getUnitId() == unitId) {
				amount++;
			}
		}
		return amount;
	}

	@Override
	public long getChildAmount(int unitId) {
		long amount = 0;
		for (IParentUnit parent : parentList) {
			amount += parent.getChildAmount(unitId);
		}
		return amount;
	}

	@Override
	public List<IParentUnit> getParents() {
		return parentList;
	}

	@Override
	public String toString() {
		ToStringBuilder builder = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
		builder.append(type);
		builder.append(parentList);
		return builder.toString();
	}

	@Override
	public boolean equals(Object object) {
		if (object == this) {
			return true;
		}
		if (object instanceof UnitList) {
			UnitList list = (UnitList) object;
			EqualsBuilder equals = new EqualsBuilder();
			equals.append(this.type, list.type);
			equals.append(this.parentList, list.parentList);
			return equals.isEquals();
		}
		return false;
	}

	@Override
	public long count(int unitId, long amount) {
		if (amount < 1) {
			throw new IllegalArgumentException("amount=" + amount);
		}
		int parentAmount = getParentAmount(unitId);
		if (parentAmount > 0) {
			return parentAmount / amount;
		}
		long childAmount = getChildAmount(unitId);
		return childAmount / amount;
	}

	@Override
	public boolean contains(int unitId, long amount) {
		return count(unitId, amount) > 0;
	}

}
